<?php

namespace app\api\controller;

use app\BaseController;
use app\model\CouponOrderSid;
use think\facade\Db;
use app\common\service\Taototo;;
use think\Request;


/**
 * Class Index
 * @package app\index\controller
 */
class MovieOrder extends BaseController
{
    use \app\common\traits\Order; //统一管理

    private $taototo = null;
    private $servType = PRODUCT_FILM_SERV;

    protected $middleware = [
        \app\middleware\ApiChannel::class    => ['except' => ['cancel', 'showEnCode']],
        \app\middleware\ApiUserAuthV2::class => ['except' => ['showEnCode']],
    ];

    protected function initialize()
    {
        $this->request->servType = PRODUCT_FILM_SERV;
        $this->request->servName = '影票';
        parent::initialize();
    }

    public function __construct()
    {
        try {
            $this->taototo = new Taototo();
        } catch (\Exception $e) {
            exit(json_encode(['code' => 0, 'message' => $e->getMessage()]));
        }
    }

    /**
     * 订单列表
     */
    public function list(Request $request)
    {
        $where[] = ['agent_id', '=', $request->agentChannel['agent_id']];
        $where[] = ['user_id', '=', $request->user['id']];
        $where[] = ['status', '=', 2];

        $params = input('post.');
        if (!empty($params['status'])) {
            if ($params['status'] == 2) {
                // 已出票
                $where[] = ['supplier_status', 'in', [4, 5]];
            } elseif ($params['status'] == 3) {
                // 已取消
                $where[] = ['supplier_status', '=', 10];
            }
        }

        $list = Db::name('movie_order')
            ->field('id, order_id, film_image, film_name, show_time, duration,
            end_time, hall_name, cinema_name, mobile, supplier_status as status,
            order_num, total_net_price, sale_price, close_time, close_cause, refund_status,
            real_seat, ticket_code,ticket_image')
            ->where($where)
            ->order('id desc')
            ->paginate([
                'page' => $params['page'] ?? 1,
                'list_rows' => $params['list_rows'] ?? 10,
            ])->toArray();
        foreach ($list['data'] as $k => $v) {
            if ($v['status'] <= 2) {
                $list['data'][$k]['status'] = 1;    // 待出票
            } elseif ($v['status'] <= 5) {
                $list['data'][$k]['status'] = 2;    // 已出票
            } else {
                $list['data'][$k]['status'] = 3;    // 已取消
            }
            $ticket_code =  json_decode($v['ticket_code'], true);
            $ticket_image = json_decode($v['ticket_image'], true);

            $list['data'][$k]['ticket_code'] = $ticket_code;
            $list['data'][$k]['ticket_image'] = $ticket_image;

            if (!empty($ticket_code)) {

                $arr = [];

                //如果二维码为空
                foreach ($ticket_code as $code) {
//                    $arr[] = 'https://api.qrserver.com/v1/create-qr-code/?size=500x500&data=' . $code;
                    $arr[] = env('app.api_url').'/qr?code=' . $code;
                }

                $list['data'][$k]['ticket_image']= $arr;

            }

            $list['data'][$k]['order_id'] = strval($v['order_id']);
        }

        return success('操作成功', $list);
    }

    /**
     * 下单
     */
    public function create(Request $request)
    {
        $agentId = $request->agentChannel['agent_id'];

        $agentServiceConfig = Db::name('agent_service_config')
            ->field('status, value')
            ->where('agent_id', $agentId)
            ->where('serv_type', $this->servType)
            ->find();
        if (empty($agentServiceConfig) || $agentServiceConfig['status'] != 1) {
            return fail('影票接口尚未开通，请联系商务进行开通');
        }

        // 代理商返佣比例
        $commissionRate = $agentServiceConfig['value'];
        if ($commissionRate < 0) {
            $commissionRate = 0;
        } elseif ($commissionRate > 100) {
            $commissionRate = 100;
        }

        // 获取供应商
        $supplierIds = Db::name('agent_supplier')
            ->where('agent_id', $agentId)
            ->where('serv_type', $this->servType)
            ->column('supplier_id');
        if (empty($supplierIds)) {
            return fail('通道维护中');
        }
        $supplier = Db::name('base_supplier')
            ->field('id, settle_value')
            ->whereIn('id', $supplierIds)
            ->where('serv_type', $this->servType)
            ->whereNull('deleted_at')
            ->select()
            ->toArray();
        if (empty($supplier)) {
            return fail('通道维护中。');
        }
        // 随机搞一个供应商
        $index = array_rand($supplier);
        $supplier = $supplier[$index];


        $params = input('post.');
        if (empty($params['showId'])) {
            return fail('场次 id 不能为空');
        }
        if (empty($params['mobile'])) {
            return fail('请填写手机号');
        }
        $show = Db::name('taototo_schedule')
            ->where('show_id', $params['showId'])
            ->order('id desc')
            ->find();
        if (empty($show)) {
            return fail('支付超时，请刷新重试');
        }
        $film = Db::name('taototo_film')
            ->field('pic')
            ->where('film_id', $show['film_id'])
            ->find();

        $netPrice = $show['net_price'];

        // 折扣
        $discount = Db::name('taototo_cinema')
            ->where('cinema_id', $show['cinema_id'])
            ->value('down_discount_rate');
        if (empty($discount)) {
            $discount = 1.0;
        }
        $areaPrice = $this->taototo->getScheduleAreaPriceArr($show['schedule_area']);

        if (empty($params['seats'])) {
            return fail('请选择座位');
        }
        $seats = $params['seats'];
        unset($params['seats']);
        $totalNetPrice = 0;
        $seat = [];
        $seatId = [];
        $seatNo = [];
        $areas = [];
        $orderNum = 0;
        foreach ($seats as $k => $v) {
            if (isset($areaPrice[$v['area']]['price'])) {
                $price = $areaPrice[$v['area']]['price'];
            } else {
                $price = $netPrice;
            }
            if ($price <= 0) {
                return fail('座位价格有误，请刷新重试');
            }
            $seats[$k]['netPrice'] = $price;
            $totalNetPrice += $price;
            if (!empty($v['lovestatus'])) {
                $seat[] = $v['seatNo'] . '(情侣座)';
            } else {
                $seat[] = $v['seatNo'];
            }
            $seatId[] = $v['seatId'];
            $seatNo[] = $v['seatNo'];
            if (!empty($v['area'])){
                $areas[] = $v['area'];
            }
            $orderNum += 1;
        }
        $salePrice = intval(strval($totalNetPrice * $discount));
        if ($salePrice <= 0) {
            return fail('订单价格有误，请刷新重试');
        }

        // 预充模式，判断代理商账户余额
        if (SETTLE_TYPE_PREPAY == $request->agentChannel['settle_type']) {
            $balance = Db::name('agent')
                ->where('id', $agentId)
                ->where('status', 1)
                ->value('balance');
            if (empty($balance) || $balance < $salePrice) {
                return fail('商户账户余额不足');
            }
        }

        $orderId = $this->generateOrderId();
        if (false === $orderId) {
            return fail('订单号生成失败，请刷新重试');
        }

        $taototoOrderParams = [
            'showId' => $params['showId'],
            'seat' => implode(',', $seat),
            'reservedPhone' => $params['mobile'],
            'thirdOrderId' => $orderId,
            'notifyUrl' => $request->domain() . '/api/notify_v2/taototo',
            'acceptChangeSeat' => $params['acceptChangeSeat'] ?? 0,
            'seatId' => implode('|', $seatId),
            'seatNo' => implode('|', $seatNo),
            'netPrice' => $totalNetPrice,
            'orderPrice' => $salePrice,
        ];
        if ($areas){
            $taototoOrderParams['area'] = implode('|', $areas);
        }
        unset($seat);
        unset($seatId);
        unset($seatNo);
        //生成sid
        $sid = (new CouponOrderSid())->generateNew(PRODUCT_FILM_SERV);
        Db::startTrans();
        try {
            Db::name('movie_order')->insert([
                'agent_id' => $request->agentChannel['agent_id'],
                'settle_type' => $request->agentChannel['settle_type'],
                'user_id' => $request->user['id'],
                'channel_id' => $request->agentChannel['id'],
                'order_id' => $orderId,
                'out_order_id' => $orderId,
                'supplier_order_id' => '',
                'film_id' => $show['film_id'],
                'film_image' => $film['pic'] ?? '',
                'film_name' => $show['film_name'],
                'show_time' => $show['show_time'],
                'end_time' => $show['end_time'],
                'duration' => $show['duration'],
                'hall_name' => $show['hall_name'],
                'seats_str' => $taototoOrderParams['seat'],
                'cinema_id' => $show['cinema_id'],
                'cinema_name' => $show['cinema_name'],
                'accept_change_seat' => $taototoOrderParams['acceptChangeSeat'],
                'mobile' => $params['mobile'],
                'status' => 1,
                'order_num' => $orderNum,
                'total_net_price' => $totalNetPrice,
                'commission_rate' => $commissionRate,    // 代理商返佣比例
                'sale_price' => $salePrice, // 销售价
                'real_seat' => '',
                'ticket_code' => '[]',
                'ticket_image' => '[]',
                'settle_time' => 0,
                'supplier_id' => $supplier['id'],
                'plan_type' => $show['plan_type'],
                'sid' => $sid, //sid写入
            ]);
            Db::name('taototo_order')
                ->insert([
                    'agent_id' => $request->agentChannel['agent_id'],
                    'order_id' => $orderId,
                    'params' => json_encode($taototoOrderParams, JSON_UNESCAPED_UNICODE),
                    'status' => 1,
                    'result' => '',
                ]);
            Db::name('movie_pay_log')
                ->insert([
                    'agent_id' => $request->agentChannel['agent_id'],
                    'channel_id' => $request->agentChannel['id'],
                    'user_id' => $request->user['id'],
                    'order_id' => $orderId,
                    'amount' => $salePrice,
                    'supplier_id' => $this->taototo->getId(),
                    'settle_type' => $request->agentChannel['settle_type'],
                ]);
            Db::name('base_supplier')
                ->where('id', $supplier['id'])
                ->inc('order_count', 1)
                ->update();

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return fail('下单失败：' . $e->getMessage() . $e->getLine());
        }

        return success('下单成功', [
            'order_id' => $orderId,
        ]);
    }

    /**
     * 订单取消
     */
    public function cancel(Request $request)
    {
        $orderId = input('post.order_id');
        $order = Db::name('movie_order')
            ->where('order_id', $orderId)
            ->where('user_id', $request->user['id'])
            ->find();
        if (empty($order)) {
            return fail('订单不存在');
        }

        if ($order['status'] == 3) {
            return fail('取消成功');
        }
        if ($order['supplier_status'] != 1) {
            return fail('该订单无法取消');
        }

        Db::startTrans();
        try {
            Db::name('movie_order')
                ->where('order_id', $orderId)
                ->update([
                    'supplier_status' => 10,
                    'close_time' => time(),
                    'close_cause' => '用户取消',
                ]);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return fail('取消失败：' . $e->getMessage());
        }

        return success('取消成功');
    }

    /**
     * 生成订单号
     */
    private function generateOrderId()
    {
        for ($i = 0; $i < 21; $i++) {
            $orderId = date('ymdHis') . str_pad(mt_rand(0, 999999), 6, STR_PAD_LEFT);
            $id = Db::name('movie_order')
                ->where('order_id', $orderId)
                ->value('id');
            if (empty($id)) {
                return $orderId;
            }
        }

        return false;
    }

    /**
     * 返回前端加密后的影票order_id
     * @access public
     * @author ymzhang
     * @date 2022-08-15 15:00
     */
    public function showEnCode(Request $request)
    {
        $params = $request->all();
        $msg = dmjValidate([
            'code' => 'require',
        ], [], $params);
        if ($msg) {
            return $msg;
        }
        //https://hfcs.dmjvip.com/topup/order/movieOrderDetail?filmCode=klWMMf
        $baseUrl = env('app.api_url');
        $headerUrl = $baseUrl.'/topup/order/movieOrderDetail?filmCode='.$params['code'];
        return redirect($headerUrl);
    }
}
